package com.hx.util.file;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class FileUtil {

	private String message = "";

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * 获得文件所对应的输入流
	 * 
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public static InputStream getInputStream(File file) throws Exception {
		return new BufferedInputStream(new FileInputStream(file));
	}

	/**
	 * 获得文件字节流
	 * 
	 * @param inputStream
	 * @return
	 * @throws Exception
	 */
	public static byte[] getFileBytes(InputStream inputStream) throws Exception {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(
				1024);
		byte[] block = new byte[512];

		while (true) {
			int readLength = inputStream.read(block);
			if (readLength == -1) {
				break;
			}
			byteArrayOutputStream.write(block, 0, readLength);
		}

		byte[] retValue = byteArrayOutputStream.toByteArray();
		byteArrayOutputStream.close();

		return retValue;
	}

	/**
	 * 将源文件拷贝到目标文件
	 * 
	 * @param src
	 *            写源文件地址，需文件名
	 * @param des
	 *            写目标文件地址，无需文件名
	 */
	public boolean copyFile(String src, String des) {
		File srcFile = new File(src);
		File desDir = new File(des);
		File desFile = new File(des + "/" + srcFile.getName());
		// 判断源文件是否存在
		if (!srcFile.exists()) {
			this.setMessage("源文件不存在！");
			return false;
		} else if (!srcFile.isFile()) {
			this.setMessage("源文件格式错！");
			return false;
		}
		// 判断源文件是否存在
		if (!desDir.exists()) {
			this.setMessage("目标目录不存在！");
			return false;
		} else if (!desDir.isDirectory()) {
			this.setMessage("不是有效的目录！");
			return false;
		}
		BufferedReader reader = null;
		BufferedWriter writer = null;
		String str;
		try {
			reader = new BufferedReader(new FileReader(srcFile));
			writer = new BufferedWriter(new FileWriter(desFile));
			// 判断目标文件是否存在及其格式，不存在就创建，格式不对先删除，存在就替代
			if (!desFile.exists() || !desFile.isFile()) {
				if (desFile.exists()) {
					desFile.delete();
				}
				desFile.createNewFile();
			}
			// 从源文件读取数据，并写入目标文件
			str = reader.readLine();
			while (str != null) {
				writer.write(str);
				writer.newLine();
				str = reader.readLine();
			}
		} catch (IOException e) {
			this.setMessage(e.getMessage());
			return false;
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					this.setMessage(e.getMessage());
				}
			}
			if (writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					this.setMessage(e.getMessage());
				}
			}
		}
		return true;
	}

	private List<File> fileList = new ArrayList<File>();

	/**
	 * 列出所有文件
	 * 
	 * @param srcFile
	 */
	private void file(File srcFile) {
		if (srcFile.isDirectory()) {
			String[] files = srcFile.list();

			for (int i = 0; i < files.length; i++) {
				File f = new File(srcFile + "/" + files[i]);
				// 如果是文件加入列表，否则递归列出
				if (f.isFile()) {
					fileList.add(f);
				} else
					file(f);
			}
		} else
			this.setMessage(srcFile.getAbsolutePath() + "不是目录");
	}

	/**
	 * 建立目录
	 * 
	 * @param des
	 * @throws IOException
	 */
	private void mkdir(File des) {
		if (!des.exists() || !des.isDirectory()) {
			mkdir(des.getParentFile());
			if (des.exists()) {
				des.delete();
			}
			des.mkdir();
		}
	}

	/**
	 * 复制目录 将源目录下所有文件拷贝到目标目录下
	 * 
	 * @param src
	 *            源目录
	 * @param des
	 *            目标目录
	 */
	public boolean copyDir(String src, String des) {
		File srcFile = new File(src);
		if (!srcFile.exists()) {
			this.setMessage("源目录不存在！");
			return false;
		} else if (!srcFile.isDirectory()) {
			this.setMessage(src + "不是有效的目录！");
			return false;
		}
		file(srcFile);

		for (int i = 0; i < fileList.size(); i++) {
			String srcName = ((File) fileList.get(i)).getPath();
			String desName = srcName.substring(src.length(), srcName.length());
			desName = des + desName;
			File dir = new File(desName).getParentFile();
			mkdir(dir);

			if (!copyFile(srcName, dir.getPath())) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 复制文件
	 * 
	 * @author n.Die_Ssming
	 * @version 1.0 5/3/2011
	 * @since 1.0
	 * @param src
	 *            源文件路径
	 * @param des
	 *            目标文件路径
	 */
	public static Boolean copy(String src, String des) {
		try {
			if (!src.equals(des)) {
				FileChannel srcChannel = new FileInputStream(src).getChannel();
				FileChannel dstChannel = new FileOutputStream(des).getChannel();
				dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
				srcChannel.close();
				dstChannel.close();
			}
			return true;
		} catch (IOException ex) {
			ex.printStackTrace();
			return false;
		}
	}

	/**
	 * zip解压并返回指定文件位置
	 * @author Alex.duan
	 * @param zipFileName 要解压文件路径
	 * @param extPlace	要解压到位置
	 * @param fileName   此文件名所处位置
	 * @return String
	 */
	@SuppressWarnings("unused")
	public static String extZipFileList(String zipFileName, String extPlace,String fileName) {
		StringBuffer requestUrl = new StringBuffer("/");
		try {
			ZipInputStream in = new ZipInputStream(new FileInputStream(
					zipFileName));

			ZipEntry entry = null;
			while ((entry = in.getNextEntry()) != null) {

				String entryName = entry.getName();

				if (entry.isDirectory()) {
					File file = new File(extPlace + entryName);
					file.mkdirs();
				} else {
					int location = entryName.indexOf(fileName);
					if(location!=-1){
						requestUrl.append(entryName.subSequence(0, location));
					}
					FileOutputStream os = new FileOutputStream(extPlace
							+ entryName);

					// Transfer bytes from the ZIP file to the output file
					byte[] buf = new byte[1024];

					int len;
					while ((len = in.read(buf)) > 0) {
						os.write(buf, 0, len);
					}
					os.close();
					in.closeEntry();

				}
			}

		} catch (IOException e) {
			requestUrl = new StringBuffer();
		}
		return requestUrl.toString();
	}
	public static void main(String[] args) {
		extZipFileList("D:\\indexDir.zip", "D:\\", "");
	}
}
